]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
popupMenu: add alternate menu item
authorRay Strode <rstrode@redhat.com>
Mon, 21 Feb 2011 20:25:56 +0000 (15:25 -0500)
committerRay Strode <rstrode@redhat.com>
Tue, 22 Feb 2011 23:46:57 +0000 (18:46 -0500)
This is special menu item that can alternate
between two choices when you hit the alt key.

It will be useful for getting a hybrid
suspend/power off menu item.

https://bugzilla.gnome.org/show_bug.cgi?id=636680

data/theme/gnome-shell.css
js/ui/popupMenu.js

index 7476390534af6cbddeea49a5c30861a76c8159bb..248bb0c6a1fecd5bb2f60df7bf620d4594a07a56 100644 (file)
@@ -140,6 +140,10 @@ StTooltip StLabel {
     height: 1em;
 }
 
+.popup-alternating-menu-item:alternate {
+    font-weight: bold;
+}
+
 .popup-slider-menu-item {
     height: 1em;
     min-width: 15em;
index 00cc02082bd8c59e969cfc3cbb7d22a70b3fa30a..0a26ba71e3afe18007f4035a5f35f2a909a30db8 100644 (file)
@@ -328,6 +328,107 @@ PopupSeparatorMenuItem.prototype = {
     }
 };
 
+const PopupAlternatingMenuItemState = {
+    DEFAULT: 0,
+    ALTERNATIVE: 1
+}
+
+function PopupAlternatingMenuItem() {
+    this._init.apply(this, arguments);
+}
+
+PopupAlternatingMenuItem.prototype = {
+    __proto__: PopupBaseMenuItem.prototype,
+
+    _init: function(text, alternateText, params) {
+        PopupBaseMenuItem.prototype._init.call(this, params);
+        this.actor.add_style_class_name('popup-alternating-menu-item');
+
+        this._text = text;
+        this._alternateText = alternateText;
+        this.label = new St.Label({ text: text });
+        this.state = PopupAlternatingMenuItemState.DEFAULT;
+        this.addActor(this.label);
+
+        this.actor.connect('notify::mapped', Lang.bind(this, this._onMapped));
+    },
+
+    _onMapped: function() {
+        if (this.actor.mapped) {
+            this._capturedEventId = global.stage.connect('captured-event',
+                                                         Lang.bind(this, this._onCapturedEvent));
+            this._updateStateFromModifiers();
+        } else {
+            if (this._capturedEventId != 0) {
+                global.stage.disconnect(this._capturedEventId);
+                this._capturedEventId = 0;
+            }
+        }
+    },
+
+    _setState: function(state) {
+        if (this.state != state) {
+            if (state == PopupAlternatingMenuItemState.ALTERNATIVE && !this._canAlternate())
+                return;
+
+            this.state = state;
+            this._updateLabel();
+        }
+    },
+
+    _updateStateFromModifiers: function() {
+        let [x, y, mods] = global.get_pointer();
+        let state;
+
+        if ((mods & Clutter.ModifierType.MOD1_MASK) == 0) {
+            state = PopupAlternatingMenuItemState.DEFAULT;
+        } else {
+            state = PopupAlternatingMenuItemState.ALTERNATIVE;
+        }
+
+        this._setState(state);
+    },
+
+    _onCapturedEvent: function(actor, event) {
+        if (event.type() != Clutter.EventType.KEY_PRESS &&
+            event.type() != Clutter.EventType.KEY_RELEASE)
+            return false;
+
+        let key = event.get_key_symbol();
+
+        if (key == Clutter.KEY_Alt_L || key == Clutter.KEY_Alt_R)
+            this._updateStateFromModifiers();
+
+        return false;
+    },
+
+    _updateLabel: function() {
+        if (this.state == PopupAlternatingMenuItemState.ALTERNATIVE) {
+            this.actor.add_style_pseudo_class('alternate');
+            this.label.set_text(this._alternateText);
+        } else {
+            this.actor.remove_style_pseudo_class('alternate');
+            this.label.set_text(this._text);
+        }
+    },
+
+    _canAlternate: function() {
+        if (this.state == PopupAlternatingMenuItemState.DEFAULT && !this._alternateText)
+            return false;
+        return true;
+    },
+
+    updateText: function(text, alternateText) {
+        this._text = text;
+        this._alternateText = alternateText;
+
+        if (!this._canAlternate())
+            this._setState(PopupAlternatingMenuItemState.DEFAULT);
+
+        this._updateLabel();
+    }
+};
+
 function PopupSliderMenuItem() {
     this._init.apply(this, arguments);
 }